#include "stdafx.h"
#include "CUDA_MatFunc.h"

//#define CU_DEBUG_MODE

#ifdef CU_DEBUG_MODE
	#define CUDA_CHECK_ERROR(err)											\
		if (err != cudaSuccess) {											\
			printf("Cuda error: %s\n", cudaGetErrorString(err));			\
			printf("Error in file: %s, line: %i\n", __FILE__, __LINE__);	\
		}
#else
	#define CUDA_CHECK_ERROR
#endif
	
#define BLOCK_DIM 1

__global__ void __cu_mul24(int* outputMatrix, int a, int b)
{
	outputMatrix[0] = __mul24(a, b);
}

int cu_mul24(int a, int b)
{	

#ifdef CU_DEBUG_MODE
	if(sizeof(a)>24 || sizeof(b)>24)
	{
		printf("cu_mul24 error: size to large! (a = %d, b = %d)\n", sizeof(a), sizeof(b));
		//return (int)cu_fmul_rn((int)a, (int)b);
		return 0;
	}
#endif
	
	int outputMatrix;
    int* devOutputMatrix;
    
    CUDA_CHECK_ERROR(cudaMalloc((void**)&devOutputMatrix, sizeof(int)));
    
    __cu_mul24<<<dim3(1, 1, 1), dim3(1, 1, 1)>>>(devOutputMatrix, a, b);

    CUDA_CHECK_ERROR(cudaMemcpy(&outputMatrix, devOutputMatrix, sizeof(int), cudaMemcpyDeviceToHost));

	return outputMatrix;
}

__global__ void __cu_mulhi(int* outputMatrix, int a, int b)
{
	outputMatrix[0] = __mulhi(a, b);
}

int cu_mulhi(int a, int b)
{
	int outputMatrix;
    int* devOutputMatrix;
    
    CUDA_CHECK_ERROR(cudaMalloc((void**)&devOutputMatrix, sizeof(int)));
    
    __cu_mulhi<<<dim3(1, 1, 1), dim3(1, 1, 1)>>>(devOutputMatrix, a, b);

    CUDA_CHECK_ERROR(cudaMemcpy(&outputMatrix, devOutputMatrix, sizeof(int), cudaMemcpyDeviceToHost));

	return outputMatrix;
}

__global__ void __cu_fmul_rn(float* outputMatrix, float a, float b)
{
	outputMatrix[0] = __fmul_rn(a, b);
}

float cu_fmul_rn(float a, float b)
{
	float outputMatrix;
    float* devOutputMatrix;
    
    CUDA_CHECK_ERROR(cudaMalloc((void**)&devOutputMatrix, sizeof(float)));
    
    __cu_fmul_rn<<<dim3(1, 1, 1), dim3(1, 1, 1)>>>(devOutputMatrix, a, b);

    CUDA_CHECK_ERROR(cudaMemcpy(&outputMatrix, devOutputMatrix, sizeof(float), cudaMemcpyDeviceToHost));

	return outputMatrix;
}